# 先导入系统库，再导入框架库，最后导入用户库
import platform
import django
from django.views.generic.base import TemplateView
from django.shortcuts import render, HttpResponseRedirect
from django.views.decorators.http import require_http_methods
from django.contrib.auth import authenticate, login
from django.urls import reverse
from django.contrib.auth.models import User
from appinput.models import App
from serverinput.models import Server
from deploy.models import DeployPool
from .forms import LoginForm, RegisterForm


# TemplateView只需要爨地模板名称并传递一些上下文参数即可，不需要具体Model绑定
class IndexView(TemplateView):
    template_name = "manabe/index.html"

    # 该方法用于传递跟多上下文参数
    def get_context_data(self, **kwargs):
        context = super().get_context_data()
        context['current_page'] = 'index'
        context['app_count'] = App.objects.count()
        context['server_count'] = Server.objects.count()
        context['deploy_count'] = DeployPool.objects.count()
        # 获取IP地址
        context['REMOTE_ADDR'] = self.request.META.get("REMOTE_ADDR")
        # 获取浏览器版本
        context['HTTP_USER_AGENT'] = self.request.META.get("HTTP_USER_AGENT")
        # 获取浏览器语言
        context['HTTP_ACCEPT_LANGUAGE'] = self.request.META.get("HTTP_ACCEPT_LANGUAGE")
        # 操作系统
        context['platform'] = platform.platform()
        context['python_version'] = platform.python_version()
        context['django_version'] = django.get_version()
        return context


def redirect_login(request):
    login_url = reverse('index')
    return HttpResponseRedirect(request.POST.get('next', login_url) or login_url)


@require_http_methods(["GET", "POST"])
def user_login(request):
    error = []
    if request.method == 'POST':
        form = LoginForm(request.POST)
        # 从前端login页面获得input标签中name为‘vc’的用户输入验证码
        vc = request.POST['vc']
        # 将用户输入验证码upper大写之后比较session中保存的验证码“verify_code”是否相同
        if vc.upper() != request.session['verify_code']:
            error.append('验证码错误！')
            return render(request, "accounts/login.html", locals())
        if form.is_valid():
            data = form.cleaned_data
            username = data['username']
            password = data['password']
            user = authenticate(username=username, password=password)
            if user and user.is_active:
                login(request, user)
                return redirect_login(request)
            else:
                error.append('请输入正确的用户名和密码！')
                return render(request, "accounts/login.html", locals())
        else:
            return render(request, "accounts/login.html", locals())
    else:
        form = LoginForm()
        return render(request, "accounts/login.html", locals())


# 只允许POST和GET请求，别的请求都会被拒绝
@require_http_methods(["GET", "POST"])
def user_register(request):
    # 出错列表，收集错误信息
    error = []
    if request.method == "POST":
        form = RegisterForm(request.POST)
        # 该方法根据表单中定义的字段类型和自定义验证方法来验证提交的数据。
        # 验证后的数据保存再实例化后返回的cleaned_data中，其是个字典数据格式
        # 错误信息，保存在form.errors中，我们没有使用
        if form.is_valid():
            data = form.cleaned_data
            username = data['username']
            email = data['email']
            password = data['password']
            password2 = data['password2']
            # 搜索数据库中，该用户名不存在的情况下才可以接着操作
            # __iexact是不存在的数据筛选条件
            if not User.objects.all().filter(username__iexact=username):
                # 判断两个密码是否相同，用到了表单的内置方法
                if form.pwd_validate(password, password2):
                    user = User.objects.create_user(
                        username=username,
                        password=password,
                        email=email
                    )
                    user.save()
                    # 认证用户的密码是否有效
                    user = authenticate(username=username, password=password)
                    login(request, user)
                    return redirect_login(request)
                else:
                    error.append('密码不一致， 请确认')
            else:
                error.append('已存在相同的用户名，请更换用户名')
        else:
            error.append('请确认各个输入框无误')
        return render(request, 'accounts/register.html', locals())
    else:
        form = RegisterForm()
        return render(request, 'accounts/register.html', locals())
